package com.jy.oms.framework.util;


import org.apache.commons.lang3.StringUtils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.util.Date;
import java.util.Objects;


/**
 * @author Jokercheng
 */
public class DateUtils {

    public static final String YYYY_MM_DD_FORMATTER = "yyyy-MM-dd";
    public static final String HH_MM_FORMATTER = "HH:mm";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public static LocalDateTime date2LocalDate(Date date) {
        if (null == date) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    public static LocalDate dateToLocalDate(Date date) {
        if(null == date) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    public static LocalDate string2YMDLocalDate(String dateStr){
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDate.parse(dateStr, df);
    }

    /**
     * 注意此方法使用，pattern为yyyy-mm-dd是不支持的，需使用string2YMDDate方法
     */
    public static Date string2Date(String dateStr, String pattern) {
        if (null == dateStr) {
            return null;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, df);
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    public static Date string2YMDDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        LocalDate localDate = string2YMDLocalDate(dateStr);
        return localDateToDate(localDate);
    }

    public static String date2String(Date date, String pattern) {
        if (null == date) {
            return null;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
        return df.format(date2LocalDate(date));
    }

    public static String date2String(Temporal date, String pattern) {
        if (null == date) {
            return null;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
        return df.format(date);
    }

    public static Date localDate2Date(LocalDateTime localDateTime) {
        if (null == localDateTime) {
            return null;
        }
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    public static Date localDateToDate(LocalDate localDate) {
        if (null == localDate) {
            return null;
        }
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    public static Date now() {
        return new Date();
    }

    public static Date before(long dayNum) {
        return localDate2Date(LocalDateTime.now().minusDays(dayNum));
    }

    public static LocalDateTime max(Date date1, Date date2) {
        if (date1 == null && date2 == null) {
            return null;
        }
        if (date1 == null) {
            return date2LocalDate(date2);
        }
        if (date2 == null) {
            return date2LocalDate(date1);
        }
        return max(date2LocalDate(date1), date2LocalDate(date2));
    }

    public static LocalDateTime min(Date date1, Date date2) {
        if (date1 == null && date2 == null) {
            return null;
        }
        if (date1 == null) {
            return date2LocalDate(date2);
        }
        if (date2 == null) {
            return date2LocalDate(date1);
        }
        return min(date2LocalDate(date1), date2LocalDate(date2));
    }

    public static LocalDateTime max(LocalDateTime localDate1, LocalDateTime localDate2) {
        return localDate1.isBefore(localDate2) ? localDate2 : localDate1;
    }

    public static LocalDateTime min(LocalDateTime localDate1, LocalDateTime localDate2) {
        return localDate1.isBefore(localDate2) ? localDate1 : localDate2;
    }

    public static long toMills(LocalDateTime localDateTime){
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        return zonedDateTime.toInstant().toEpochMilli();
    }

    public static long toSeconds(LocalDateTime localDateTime){
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        return zonedDateTime.toEpochSecond();
    }


    public static String personalShow(Date date) {
        final LocalDateTime localDateTime = date2LocalDate(date);
        if (isToday(localDateTime.toLocalDate())) {
            return "今天 " + localDateTime.format(DateTimeFormatter.ofPattern("HH:mm"));
        } else if (isTomorrow(localDateTime.toLocalDate())) {
            return "明天 " + localDateTime.format(DateTimeFormatter.ofPattern("HH:mm"));
        } else if (isYesterday(localDateTime.toLocalDate())) {
            return "昨天 " + localDateTime.format(DateTimeFormatter.ofPattern("HH:mm"));
        } else {
            return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
        }
    }

    private static boolean isToday(LocalDate localDate) {
        return LocalDate.now().compareTo(localDate) == 0;
    }

    private static boolean isTomorrow(LocalDate localDate) {
        Objects.requireNonNull(localDate);
        return LocalDate.now().plusDays(1).compareTo(localDate) == 0;
    }

    private static boolean isYesterday(LocalDate localDate) {
        Objects.requireNonNull(localDate);
        return LocalDate.now().minusDays(1).compareTo(localDate) == 0;
    }

}
